package com.ilink.groundservice.service.impl.AiX;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ilink.groundservice.entity.PO.AiX.AiXArea;
import com.ilink.groundservice.entity.PO.AiX.AiXDelete;
import com.ilink.groundservice.entity.PO.AiX.AiXSceneBase;
import com.ilink.groundservice.entity.PO.AiX.AiXScenePhaseBase;
import com.ilink.groundservice.entity.PO.AiX.AiXSceneSubPhase;
import com.ilink.groundservice.entity.PO.AiX.AiXSubPhaseResource;
import com.ilink.groundservice.entity.PO.AiX.AiXTag;
import com.ilink.groundservice.entity.PO.AiX.AiXTagConnect;
import com.ilink.groundservice.entity.VO.AiX.AiXSubPhaseResourceResponse;
import com.ilink.groundservice.mapper.AiX.AiXAreaMapper;
import com.ilink.groundservice.mapper.AiX.AiXDeleteMapper;
import com.ilink.groundservice.mapper.AiX.AiXSceneBaseMapper;
import com.ilink.groundservice.mapper.AiX.AiXScenePhaseBaseMapper;
import com.ilink.groundservice.mapper.AiX.AiXSceneSubPhaseMapper;
import com.ilink.groundservice.mapper.AiX.AiXSubPhaseResourceMapper;
import com.ilink.groundservice.service.AiX.AiXSceneSubPhaseService;
import com.ilink.groundservice.mapper.AiX.AiXTagMapper;
import com.ilink.groundservice.mapper.AiX.AiXTagConnectMapper;
import com.ilink.ilinkapi.dto.ground.AiX.AiXSubPhaseResourceInsertRequest;
import com.ilink.ilinkapi.dto.ground.AiX.AiXSubPhaseResourceUpdateRequest;
import com.ilink.ilinkapi.dto.ground.AiX.AiXSubPhaseUpdateRequest;
import com.ilink.ilinkcommon.domain.R;
import com.ilink.ilinkcommon.service.oss.MinioService;
import com.ilink.ilinkcommon.utils.SnowflakeIdGenerator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
* @author LENOVO
* @description 针对表【ai_x_scene_sub_phase】的数据库操作Service实现
* @createDate 2025-01-15 11:28:45
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class AiXSceneSubPhaseServiceImpl  implements AiXSceneSubPhaseService {

    private final AiXSubPhaseResourceMapper aiXSubPhaseResourceMapper;
    private final AiXTagMapper aiXTagMapper;
    private final AiXTagConnectMapper aiXTagConnectMapper;
    private final MinioService minioService;
    private final AiXSceneSubPhaseMapper aiXSceneSubPhaseMapper;
    private final AiXScenePhaseBaseMapper aiXScenePhaseBaseMapper;
    private final AiXSceneBaseMapper aiXSceneBaseMapper;
    private final AiXAreaMapper aiXAreaMapper;

    private final AiXDeleteMapper aiXDeleteMapper;

    // 根据phaseId获取所有子阶段subPhaseId的列表    
    @Override
    public R getSubPhases(Long phaseId) {
        try {
            // 根据phaseId查询所有子阶段，按sortOrder升序排序
            List<AiXSceneSubPhase> subPhases = aiXSceneSubPhaseMapper.selectList(
                new LambdaQueryWrapper<AiXSceneSubPhase>()
                    .eq(AiXSceneSubPhase::getPhaseId, phaseId)
                    .orderByAsc(AiXSceneSubPhase::getSortOrder)
            );
            
            // 提取子阶段ID列表
            List<Long> subPhaseIds = subPhases.stream()
                .map(AiXSceneSubPhase::getSubPhaseId)
                .collect(Collectors.toList());
                
            return R.ok("获取子阶段ID列表成功", subPhaseIds);
        } catch (Exception e) {
            log.error("获取子阶段ID列表失败，phaseId: " + phaseId, e);
            return R.error("获取子阶段ID列表失败");
        }
    }

    // 根据subPhaseId获取子阶段基本信息
    @Override
    public R getSubPhaseInfo(Long subPhaseId) {
        try {
            AiXSceneSubPhase subPhase = aiXSceneSubPhaseMapper.selectById(subPhaseId);
            return R.ok("获取子阶段基本信息成功", subPhase);
        } catch (Exception e) {
            log.error("获取子阶段基本信息失败，subPhaseId: " + subPhaseId, e);
            return R.error("获取子阶段基本信息失败");
        }
    }

    // 根据phaseId新增子阶段，sortOrder为当前phase的子阶段数量+1
    @Override
    @Transactional
    public R insertSubPhase(Long sceneId, Long phaseId) {
        try {   
            // 获取当前phase的子阶段数量
            int subPhaseCount = aiXSceneSubPhaseMapper.selectCount(new LambdaQueryWrapper<AiXSceneSubPhase>().eq(AiXSceneSubPhase::getPhaseId, phaseId));
            AiXSceneSubPhase subPhase = new AiXSceneSubPhase();
            subPhase.setSubPhaseId(new SnowflakeIdGenerator(1, 1).nextId());
            subPhase.setPhaseId(phaseId);
            subPhase.setSortOrder(subPhaseCount + 1);
            subPhase.setSubPhaseTitle("您可以在此处输入任务的名称");
            subPhase.setIntroduction("您可以在此处输入任务介绍，包括关键技术、实施方法及预期成果等，字数不超过150字。");
            subPhase.setSubPhaseTarget("您可以在此处输入任务目标，包括输入输出内容、使用的技术和预期结果等，字数不超过150字。");
            subPhase.setWorkRequirement("您可以在此处输入作品要求，包括任务步骤、数据格式和数量要求等，可以分条阐述，字数不超过150字。当然，本任务您也可以不要求提交作品。");
            subPhase.setWorkScore(0);
            subPhase.setWorkExist(true);
            aiXSceneSubPhaseMapper.insert(subPhase);
            return R.ok("新增子阶段成功");
        } catch (Exception e) {
            log.error("新增子阶段失败，sceneId: " + sceneId + ", phaseId: " + phaseId, e);
            return R.error("新增子阶段失败");
        }
    }

    // 修改子阶段基本信息
    @Override
    @Transactional
    public R updateSubPhase(AiXSubPhaseUpdateRequest request) {
        try {
            AiXSceneSubPhase subPhase = aiXSceneSubPhaseMapper.selectById(request.getSubPhaseId());
            if(subPhase == null) {
                return R.error("子阶段不存在");
            }
            subPhase.setSubPhaseTitle(request.getSubPhaseTitle());
            subPhase.setIntroduction(request.getIntroduction());
            subPhase.setSubPhaseTarget(request.getSubPhaseTarget());
            subPhase.setWorkRequirement(request.getWorkRequirement());
            subPhase.setWorkExist(request.getWorkExist());

            // 获取当前阶段的所有子阶段总分(除了当前修改的子阶段)
            Integer currentPhaseSubTotalScore = aiXSceneSubPhaseMapper.selectList(
                new LambdaQueryWrapper<AiXSceneSubPhase>()
                    .eq(AiXSceneSubPhase::getPhaseId, request.getPhaseId())
                    .eq(AiXSceneSubPhase::getWorkExist, true)
                    .ne(AiXSceneSubPhase::getSubPhaseId, request.getSubPhaseId())
            ).stream().mapToInt(AiXSceneSubPhase::getWorkScore).sum();

            // 获取所有阶段的总分（除了当前的阶段）
            Integer allPhaseScore = aiXScenePhaseBaseMapper.selectList(
                new LambdaQueryWrapper<AiXScenePhaseBase>()
                    .eq(AiXScenePhaseBase::getSceneId, request.getSceneId())
                    .ne(AiXScenePhaseBase::getPhaseId, request.getPhaseId())
            ).stream().mapToInt(AiXScenePhaseBase::getPhaseScore).sum();

            // 计算可用的最大分数
            Integer maxAvailableScore = 100 - allPhaseScore - currentPhaseSubTotalScore;

            // 判断给定的分数是否合理
            if (request.getWorkScore() > maxAvailableScore) {
                log.error("作业分数超出可分配范围，最大可分配分数为: " + maxAvailableScore);
                return R.error("作业分数超限","作业分数超出可分配范围，最大可分配分数为: " + maxAvailableScore);
            }

            // 获取新作业分数
            Integer newWorkScore = 0;
            // 如果request.getWorkExist()为true，则更新当前阶段的总分
            if(request.getWorkExist()) {
                // 获取新作业分数
                newWorkScore = request.getWorkScore();
            }
            AiXScenePhaseBase phase = aiXScenePhaseBaseMapper.selectById(request.getPhaseId());
            // 获取原来子阶段的作业分数
            Integer oldWorkScore = subPhase.getWorkScore();
            // 更新当前阶段的总分 = 原来总分 - 原来子阶段分数 + 新作业分数
            phase.setPhaseScore(phase.getPhaseScore() - oldWorkScore + newWorkScore);
            aiXScenePhaseBaseMapper.updateById(phase);

            subPhase.setWorkScore(newWorkScore);
            subPhase.setSortOrder(request.getSortOrder());
            subPhase.setPhaseId(request.getPhaseId());

            aiXSceneSubPhaseMapper.updateById(subPhase);

            return R.ok("修改子阶段基本信息成功");
        } catch (Exception e) {
            log.error("修改子阶段基本信息失败，subPhaseId: " + request.getSubPhaseId(), e);
            return R.error("修改子阶段基本信息失败");
        }
    }

    // 根据subPhaseId删除子阶段
    @Override
    @Transactional
    public R deleteSubPhase(Long subPhaseId) {
        try {
            // 获取子阶段下的所有资源
            List<AiXSubPhaseResource> resources = aiXSubPhaseResourceMapper.selectList(
                new LambdaQueryWrapper<AiXSubPhaseResource>()
                    .eq(AiXSubPhaseResource::getSubPhaseId, subPhaseId)
            );
            
            // 删除每个资源及其关联数据
            for (AiXSubPhaseResource resource : resources) {
                deleteSubPhaseResource(resource.getResourceId());
            }
            
            // 获取当前子阶段
            AiXSceneSubPhase subPhase = aiXSceneSubPhaseMapper.selectById(subPhaseId);
            // 如果当前子阶段有作业，则把当前阶段的总分减去当前子阶段的分
            if(subPhase.getWorkExist()) {
                AiXScenePhaseBase phase = aiXScenePhaseBaseMapper.selectById(subPhase.getPhaseId());
                phase.setPhaseScore(phase.getPhaseScore() - subPhase.getWorkScore());
                aiXScenePhaseBaseMapper.updateById(phase);
            }
            
            // 在AiXDelete表中插入删除记录
            AiXDelete deleteRecord = new AiXDelete();
            deleteRecord.setDeleteId(new SnowflakeIdGenerator(1, 1).nextId());
            
            // 查询phase获取sceneId
            AiXScenePhaseBase phase = aiXScenePhaseBaseMapper.selectById(subPhase.getPhaseId());
            // 查询scene获取areaId 
            AiXSceneBase scene = aiXSceneBaseMapper.selectById(phase.getSceneId());
            
            deleteRecord.setDeletePath(String.format("area/%d/scene/%d/phase/%d/subPhase/%d", 
                scene.getAreaId(), scene.getSceneId(), phase.getPhaseId(), subPhaseId));
            deleteRecord.setForeignId(subPhaseId);
            deleteRecord.setForeignName("ai_x_scene_sub_phase");
            aiXDeleteMapper.insert(deleteRecord);

            // 删除子阶段
            aiXSceneSubPhaseMapper.deleteById(subPhaseId);
            return R.ok("删除子阶段成功");
        } catch (Exception e) {
            log.error("删除子阶段失败，subPhaseId: " + subPhaseId, e);
            return R.error("删除子阶段失败");
        }
    }

    @Override
    public List<AiXSubPhaseResourceResponse> getSubPhaseResources(Long subPhaseId) {
        // 查询子阶段资源
        List<AiXSubPhaseResource> resources = aiXSubPhaseResourceMapper.selectList(
            new LambdaQueryWrapper<AiXSubPhaseResource>()
                .eq(AiXSubPhaseResource::getSubPhaseId, subPhaseId)
        );
        
        // 转换为响应对象
        return resources.stream()
            .map(resource -> {
                AiXSubPhaseResourceResponse response = new AiXSubPhaseResourceResponse();
                response.setResourceId(resource.getResourceId());
                // 获取封面图片URL
                String imagePath = minioService.getBucketFileUrl("dataset-square-migrate", resource.getCoverUrl());
                if(imagePath == null) {
                    log.error("资源封面未找到" + resource.getCoverUrl());
                    return null;
                }
                response.setCoverUrl(imagePath);
                response.setResourceTitle(resource.getResourceTitle());
                response.setIntroduction(resource.getIntroduction());
                response.setTargetUrl(resource.getTargetUrl());
                response.setSubPhaseId(resource.getSubPhaseId());
                
                // 获取资源标签
                List<AiXTagConnect> tagConnects = aiXTagConnectMapper.selectList(
                    new LambdaQueryWrapper<AiXTagConnect>()
                        .eq(AiXTagConnect::getConnectTableKey, resource.getResourceId())
                        .eq(AiXTagConnect::getConnectTable, "ai_x_scene_sub_phase")
                );
                
                List<String> tags = tagConnects.stream()
                    .map(tagConnect -> aiXTagMapper.selectById(tagConnect.getTagId()).getTagName())
                    .collect(Collectors.toList());
                response.setTags(tags);
                
                return response;
            })
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
    }
    @Override
    @Transactional
    public R insertSubPhaseResource(AiXSubPhaseResourceInsertRequest request) {
        SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);
        Long resourceId = idGenerator.nextId();
        
        AiXSubPhaseResource resource = new AiXSubPhaseResource();
        resource.setResourceId(resourceId);
        resource.setSubPhaseId(request.getSubPhaseId());
        resource.setResourceTitle(request.getResourceTitle());
        resource.setIntroduction(request.getIntroduction());
        resource.setTargetUrl(request.getTargetUrl());
        
        String objectName = buildResourcePath(
            request.getSubPhaseId(), 
            resourceId, 
            request.getCoverImage().getOriginalFilename()
        );
        
        boolean isUploaded = minioService.uploadBucketFile(request.getCoverImage(), "dataset-square-migrate", objectName);
        if (!isUploaded) {
            return R.error("资源封面上传失败");
        }
        resource.setCoverUrl(objectName);
        
        aiXSubPhaseResourceMapper.insert(resource);
        
        // 处理标签
        if (request.getTags() != null) {
            handleTags(request.getTags(), resourceId);
        }
        
        return R.ok("资源添加成功");
    }

    private void handleTags(List<String> tags, Long resourceId) {
        for (String tag : tags) {
            // 检查标签是否存在
            AiXTag existingTag = aiXTagMapper.selectOne(
                new LambdaQueryWrapper<AiXTag>()
                    .eq(AiXTag::getTagName, tag)
                    .last("LIMIT 1")
            );
            
            Long tagId;
            if (existingTag == null) {
                tagId = new SnowflakeIdGenerator(1, 1).nextId();
                AiXTag newTag = new AiXTag();
                newTag.setTagId(tagId);
                newTag.setTagName(tag);
                aiXTagMapper.insert(newTag);
            } else {
                tagId = existingTag.getTagId();
            }
            
            // 创建关联
            AiXTagConnect tagConnect = new AiXTagConnect();
            tagConnect.setConnectId(new SnowflakeIdGenerator(1, 1).nextId());
            tagConnect.setConnectTable("ai_x_scene_sub_phase");
            tagConnect.setConnectTableKey(resourceId);
            tagConnect.setTagId(tagId);
            aiXTagConnectMapper.insert(tagConnect);
        }
    }
    @Override
    @Transactional
    public R updateSubPhaseResource(AiXSubPhaseResourceUpdateRequest request) {
        Long resourceId = request.getResourceId();
        
        AiXSubPhaseResource resource = new AiXSubPhaseResource();
        resource.setResourceId(resourceId);
        resource.setResourceTitle(request.getResourceTitle());
        resource.setIntroduction(request.getIntroduction());
        resource.setTargetUrl(request.getTargetUrl());
        
        aiXSubPhaseResourceMapper.updateById(resource);
        
        // 删除现有标签
        aiXTagConnectMapper.delete(
            new LambdaQueryWrapper<AiXTagConnect>()
                .eq(AiXTagConnect::getConnectTableKey, resourceId)
                .eq(AiXTagConnect::getConnectTable, "ai_x_scene_sub_phase")
        );
        
        // 添加新标签
        if (request.getTags() != null) {
            handleTags(request.getTags(), resourceId);
        }
        
        return R.ok("资源更新成功");
    }
    @Override
    @Transactional
    public void updateSubPhaseResourceCover(Long resourceId, MultipartFile coverImage) {
        AiXSubPhaseResource resource = aiXSubPhaseResourceMapper.selectById(resourceId);
        if (resource == null) {
            throw new RuntimeException("资源不存在");
        }
        
        String objectName = buildResourcePath(
            resource.getSubPhaseId(), 
            resourceId, 
            coverImage.getOriginalFilename()
        );
        
        boolean isUploaded = minioService.uploadBucketFile(coverImage, "dataset-square-migrate", objectName);
        if (!isUploaded) {
            throw new RuntimeException("封面更新失败");
        }
        
        resource.setCoverUrl(objectName);
        aiXSubPhaseResourceMapper.updateById(resource);
    }
    @Override
    @Transactional
    public R deleteSubPhaseResource(Long resourceId) {
        try {
            AiXSubPhaseResource resource = aiXSubPhaseResourceMapper.selectById(resourceId);
            if (resource != null) {
                String coverUrl = resource.getCoverUrl();
                int lastSlashIndex = coverUrl.lastIndexOf('/');
                String directory = coverUrl.substring(0, lastSlashIndex + 1);
                String fileName = coverUrl.substring(lastSlashIndex + 1);
                
                boolean isDeleted = minioService.deleteBucketFile("dataset-square-migrate", directory, fileName);
                if (!isDeleted) {
                    log.error("删除OSS文件失败，资源ID: {}", resourceId);
                }
                
                // 删除标签关联
                aiXTagConnectMapper.delete(
                    new LambdaQueryWrapper<AiXTagConnect>()
                        .eq(AiXTagConnect::getConnectTableKey, resourceId)
                        .eq(AiXTagConnect::getConnectTable, "ai_x_scene_sub_phase")
                );
            }
            
            aiXSubPhaseResourceMapper.deleteById(resourceId);
            return R.ok("资源删除成功");
        } catch (Exception e) {
            log.error("删除资源失败，资源ID: {}", resourceId, e);
            return R.error("资源删除失败");
        }
    }

    private String getFileExtension(String fileName) {
        if (fileName == null) {
            return "";
        }
        int dotIndex = fileName.lastIndexOf('.');
        return dotIndex == -1 ? "" : fileName.substring(dotIndex);
    }

    private String buildResourcePath(Long subPhaseId, Long resourceId, String fileName) {
        // 获取完整的路径信息
        AiXSceneSubPhase subPhase = aiXSceneSubPhaseMapper.selectById(subPhaseId);
        AiXScenePhaseBase phase = aiXScenePhaseBaseMapper.selectById(subPhase.getPhaseId());
        AiXSceneBase scene = aiXSceneBaseMapper.selectById(phase.getSceneId());
        AiXArea area = aiXAreaMapper.selectById(scene.getAreaId());
        
        // 构建文件路径
        return "area/" + area.getAreaId() + 
               "/scene/" + scene.getSceneId() + 
               "/phase/" + phase.getPhaseId() + 
               "/sub_phase/" + subPhaseId + 
               "/resource/" + resourceId + 
               getFileExtension(fileName);
    }
}




